package main;

import javax.swing.ProgressMonitor;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.*;

public class StatusMonitor implements Runnable{

	private Object mon;
	private ArrayList<String> events;
	private ArrayList<ProgressEvent> progressEvents;
	private HashMap<String, ProgressMonitor> currentProgress;
	private boolean headless = false;

	private boolean kill;

	public synchronized void update(String message){

			events.add(message);
			notify();


	}

	public synchronized void pushEvent(ProgressEvent e){
					progressEvents.add(e);
			notify();

	}

	private synchronized void getMessage(){


			if(events.isEmpty())
				try{wait();}catch(InterruptedException e){}
			for(int i =0; i<events.size(); i++){
				System.out.println(events.get(i));
				events.remove(i);
			}

	}

	private synchronized boolean consumeProgressEvents(){
			if(progressEvents.isEmpty() && !kill)
				try{wait();}catch(InterruptedException e){}
			if(kill) return false;
			for(int i =0; i<progressEvents.size(); i++){
				ProgressEvent evt = progressEvents.get(i);
				int prog = evt.param;
				String id = evt.name;
				String msg = evt.message;
				if (evt.type == ProgressEvent.TYPE_START){
					if(headless){
						System.out.println("Starting job for " + id);
					}else{
					
						if(!currentProgress.containsKey(id)){
							ProgressMonitor pm = new ProgressMonitor(null, "Clustering task:", "Starting clustering of "+ msg, 0,100);
							pm.setMillisToPopup(10000);
							currentProgress.put(id, pm);	
							pm.setProgress(0);

						}
					}

				}else if(evt.type == ProgressEvent.TYPE_PROGRESS){
					if(headless){
						Logger.getLogger(StatusMonitor.class.getName()).log(Level.INFO,"Progress update on " + id + ": " + prog + "%");
					}else{
						if(!currentProgress.containsKey(id)){

							ProgressMonitor pm = new ProgressMonitor(null, "Clustering task:", id, 0,100);
							pm.setMillisToPopup(10000);
							currentProgress.put(id, pm);	
						}

						ProgressMonitor p = currentProgress.get(id);
						p.setProgress(prog);
					}

				}else if (evt.type == ProgressEvent.TYPE_FINISH){
					if(headless){
						System.out.println("Job " + id + " finished.");
					}else{
						currentProgress.get(id).close();
					}
				}else if (evt.type == ProgressEvent.TYPE_SHUTDOWN){
					kill = true;
					return false;
				}
				progressEvents.remove(i);
			}

			return true;
	}

	public StatusMonitor(){
		mon = new Object();
		events = new ArrayList<String>();
		progressEvents = new ArrayList<ProgressEvent>();
		currentProgress = new HashMap<String, ProgressMonitor>();
		kill = false;
	}

	public synchronized void kill(){
		kill = true;
		notify();
	}

	public void run(){
		try{
			Logger.getLogger(StatusMonitor.class.getName()).log(Level.FINE,"Status monitor");
			while(consumeProgressEvents()) {}
			Logger.getLogger(StatusMonitor.class.getName()).log(Level.FINE,"Status monitor exited");
		}catch(java.awt.HeadlessException e){
			headless = true;
			while(consumeProgressEvents()) {}
			Logger.getLogger(StatusMonitor.class.getName()).log(Level.FINE,"Status monitor is running headless.");
		}

	}

}